package cn.kailangtu.dataspot.update;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import java.io.File;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.Cache;
import okhttp3.ConnectionSpec;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class RequestUtils {

    private final String TAG = "request";

    private static final MediaType FROM_DATA = MediaType.parse("multipart/form-data");

    private static RequestUtils instance = null;

    private OkHttpClient client;

    public OkHttpClient getClient() {
        return client;
    }

    public void init(Context context) throws NoSuchAlgorithmException, KeyManagementException {
        String diskPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        File cacheDir = new File(diskPath, "http_cache");
        File cacheDir2 = new File(diskPath, "http_cache2");

        //自定义logger 网络拦截器 打印网络请求数据
        LoggerHttpInterceptor loggerHttpInterceptor = new LoggerHttpInterceptor();
        client = new OkHttpClient().newBuilder()
                .addInterceptor(loggerHttpInterceptor)
                .cache(new Cache(cacheDir, 20 * 1024 * 1024))
                //.sslSocketFactory(getIgnoreInitedSslContext().getSocketFactory(), IGNORE_SSL_TRUST_MANAGER_X509)
                //.hostnameVerifier(getIgnoreSslHostnameVerifier())
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
//                .dns(OkHttpDns.getInstance(context))
                .connectionSpecs(Arrays.asList(
                        ConnectionSpec.MODERN_TLS,
                        ConnectionSpec.CLEARTEXT // 显式允许明文
                ))
                .build();
    }


    private RequestUtils() {

    }

    public static RequestUtils getInstance() {
        if (instance == null) {
            instance = new RequestUtils();
        }

        return instance;
    }


    /**
     * 发送post请求带其他域名
     */
    public String postWithUrl(String url, String params) {

        MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
        RequestBody requestBody = RequestBody.create(JSON_TYPE, params);
        //创建一个请求对象
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)

                .build();
        try {
            Response response = client.newCall(request).execute();
            //判断请求是否成功
            if (response.isSuccessful()) {
                String resp = response.body().string();
                return resp;
            }
        } catch (IOException e) {
            Log.e(TAG, "post: 发送请求发生了错误", e);
        }
        return "";
    }


    public String Post(String url, Map<String, Object> jsonMap) throws IOException {
        // 转换参数
        String params = JSON.toJSONString(jsonMap);
        MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
        RequestBody requestBody = RequestBody.create(JSON_TYPE, params);

        //创建一个请求对象
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        Response response = client.newCall(request).execute();

        Log.d(TAG, "Post: 返回状态码" + response.code());
        //判断请求是否成功
        if (response.isSuccessful()) {
            String resp = response.body().string();
            return resp;
        }

        return "";
    }

    /**
     * 发送同步get请求,参数为字符串Map
     */
    public String get(String url, Map<String, String> params) {
        Request.Builder reqBuild = new Request.Builder().get();
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url)
                .newBuilder();
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
            }
        }
        HttpUrl httpUrl = urlBuilder.build();
        reqBuild.url(httpUrl);
        Request request = reqBuild.build();
        try {
            Response response = client.newCall(request).execute();
            //判断请求是否成功
            if (response.isSuccessful()) {
                String resp = response.body().string();
                return resp;
            }
        } catch (IOException e) {
            Log.e(TAG, "get: 发送请求发生了错误", e);
        }
        return "";
    }


    /**
     * 发送同步get请求,参数为字符串Map
     */
    public String getWithUrl(String url, Map<String, String> params) {
        Request.Builder reqBuild = new Request.Builder().get();
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url)
                .newBuilder();
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
            }
        }
        HttpUrl httpUrl = urlBuilder.build();
        String path = httpUrl.encodedPath();
        String query = httpUrl.encodedQuery();
        Log.d(TAG,"get 请求的路径: "+ path);
        Log.d(TAG,"get 请求的参数: "+ query);
        reqBuild.url(httpUrl);
        Request request = reqBuild.build();
        try {
            Response response = client.newCall(request).execute();
            //判断请求是否成功
            if (response.isSuccessful()) {
                String resp = response.body().string();
                return resp;
            }
        } catch (IOException e) {
            Log.e(TAG, "get: 发送请求发生了错误", e);
        }
        return "";
    }


    /**
     * 发送post请求
     */
    public String post(String url, String params) {

        MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
        RequestBody requestBody = RequestBody.create(JSON_TYPE, params);
        Log.i(TAG,"请求URL:"+ url);
        //创建一个请求对象
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        try {
            Response response = client.newCall(request).execute();
            //判断请求是否成功
            if (response.isSuccessful()) {
                String resp = response.body().string();
                return resp;
            }
        } catch (IOException e) {
            Log.e(TAG, "post: 发送请求"+ url+ "发生了错误"+ e);
        }
        return "";
    }

    /**
     * 发送post请求
     */
    public Response postAsync(String url, String params) {
        try {

            MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
            RequestBody requestBody = RequestBody.create(JSON_TYPE, params);
            Log.e(TAG,"接口请求,URL:"+ url);
            Log.e(TAG,"接口请求,PARAMS:"+ params);
            //创建一个请求对象
            Request request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();
            Response response =client.newCall(request).execute();
            Log.e(TAG,"接口请求,RESPONSE:"+ response.toString());
            return response;
        } catch (IOException e) {
            Log.e(TAG,e+ "请求URL报错:"+ url);
        }
        return null;
    }

    /**
     * 发送同步get请求,参数为字符串Map
     */
    public String getAysnc(String url, Map<String, String> params) {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request.Builder reqBuild = new Request.Builder().get();
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url)
                .newBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
        }
        reqBuild.url(urlBuilder.build());
        Request request = reqBuild.build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            //判断请求是否成功
            if (response.isSuccessful()) {
                String resp = response.body().string();
                return resp;
            }
        } catch (IOException e) {
            Log.e(TAG, "get: 发送请求发生了错误", e);
        }
        return "";
    }


    /**
     * X509TrustManager instance which ignored SSL certification
     */
    public static final X509TrustManager IGNORE_SSL_TRUST_MANAGER_X509 = new X509TrustManager() {


        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[] {};
        }
    };

    /**
     * Get initialized SSLContext instance which ignored SSL certification
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static SSLContext getIgnoreInitedSslContext() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, new TrustManager[] { IGNORE_SSL_TRUST_MANAGER_X509 }, new SecureRandom());
        return sslContext;
    }


    /**
     * Get HostnameVerifier which ignored SSL certification
     *
     * @return
     */
    public static HostnameVerifier getIgnoreSslHostnameVerifier() {
        return new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        };
    }

}
